public class Demo9 {
	/**
	 *两个线程两把锁会造成，死锁，这个所谓就是请求等待和保持
	 * 所谓吃着碗里的，看着锅里的
	 * 解决办法就是改变代码的逻辑，不要进行锁嵌套逻辑，进行锁并行
	 * @param args
	 * @throws InterruptedException
	 */
	public static void main1(String[] args) throws InterruptedException {
		Object locker1=new Object();
		Object locker2=new Object();
		Thread t1=new Thread(() -> {
			synchronized (locker1) {
				try {
					//这里的睡眠很重要，不睡眠的话，线程1直接将获得两把锁，线程2来不及进行加锁了
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
				synchronized (locker2) {
					System.out.println("加锁成功");
				}
			}
		});
		Thread t2=new Thread(() -> {
			synchronized (locker2) {
				try {
					//这里的睡眠很重要，不睡眠的话，线程1直接将获得两把锁，线程2来不及进行加锁了
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
				synchronized (locker1) {
					System.out.println("加锁成功");
				}
			}
		});
		t1.start();
		t2.start();
		t1.join();
		t2.join();
		System.out.println("11111111111111");
	}

	public static void main(String[] args) throws InterruptedException {
		Object locker1=new Object();
		Object locker2=new Object();
		Thread t1=new Thread(() -> {
			synchronized (locker1) {
				System.out.println("开始加锁");

				try {
					//这里的睡眠很重要，不睡眠的话，线程1直接将获得两把锁，线程2来不及进行加锁了
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
			}
			synchronized (locker2) {
				System.out.println("加锁成功");
			}
		});
		Thread t2=new Thread(() -> {
			synchronized (locker2) {
				System.out.println("开始加锁");
				try {
					//这里的睡眠很重要，不睡眠的话，线程1直接将获得两把锁，线程2来不及进行加锁了
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					throw new RuntimeException(e);
				}
			}
			synchronized (locker1) {
				System.out.println("加锁成功");
			}
		});
		t1.start();
		t2.start();
		System.out.println("11111111111111");
	}
}
